#include "delay.h"
#include "FreeRTOS.h"
/* delay macros */
#define STEP_DELAY_MS                    50

/* delay variable */
static __IO uint32_t fac_us;
static __IO uint32_t fac_ms;
/**
  * @brief  initialize delay function
  * @param  none
  * @retval none
  */
void delay_init()
{
  /* configure systick */
  systick_clock_source_config(SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV);
  fac_us = system_core_clock / (1000000U);
  fac_ms = fac_us * (1000U);
}

/**
  * @brief  inserts a delay time.
  * @param  nus: specifies the delay time length, in microsecond.
  * @retval none
  */
//void delay_us(uint32_t nus)
//{
//  uint32_t temp = 0;
//  SysTick->LOAD = (uint32_t)(nus * fac_us);
//  SysTick->VAL = 0x00;
//  SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk ;
//  do
//  {
//    temp = SysTick->CTRL;
//  }while((temp & 0x01) && !(temp & (1 << 16)));

//  SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
//  SysTick->VAL = 0x00;
//}
extern void vPortSetupTimerInterrupt( void );
extern void vTaskSuspendAll( void );
extern BaseType_t xTaskResumeAll( void );
void delay_us(u32 nus)
{ 
       u32 ticks;
       u32 told,tnow,reload,tcnt=0;
       if((0x0001&(SysTick->CTRL)) ==0)    //??????
              vPortSetupTimerInterrupt();  //??????
 
       reload = SysTick->LOAD;                     //?????????
       ticks = nus * (SystemCoreClock / 1000000);  //?????
       
       vTaskSuspendAll();//??OS??,????us??
       told=SysTick->VAL;  //??????????(?????)
       while(1)
       {
              tnow=SysTick->VAL; //??????????
              if(tnow!=told)  //???????????????
              {         
                     if(tnow<told)  //?????????,?????0
                          tcnt+=told-tnow; //???=???-???
 
                     else     //?????????,?????0?????
                            tcnt+=reload-tnow+told;   //???=????-???+???  (
                                                      //???????0) 
 
                     told=tnow;   //?????
                     if(tcnt>=ticks)break;  //????/????????,???.
              } 
       }  
       xTaskResumeAll();	//??OS??		   
} 

/**
  * @brief  inserts a delay time.
  * @param  nms: specifies the delay time length, in milliseconds.
  * @retval none
  */
void delay_ms(uint16_t nms)
{
  uint32_t temp = 0;
  while(nms)
  {
    if(nms > STEP_DELAY_MS)
    {
      SysTick->LOAD = (uint32_t)(STEP_DELAY_MS * fac_ms);
      nms -= STEP_DELAY_MS;
    }
    else
    {
      SysTick->LOAD = (uint32_t)(nms * fac_ms);
      nms = 0;
    }
    SysTick->VAL = 0x00;
    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
    do
    {
      temp = SysTick->CTRL;
    }while((temp & 0x01) && !(temp & (1 << 16)));

    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
    SysTick->VAL = 0x00;
  }
}


//void delay_ms(uint16_t mxs)
//{
//	UINT16 j,p,ms=mxs*20;
//	for(j=0; j<ms; j++)
//	{
//		for(p=0; p<ms; p++)
//		{
//			;
//		}
//	}
//}
/**
  * @brief  inserts a delay time.
  * @param  sec: specifies the delay time, in seconds.
  * @retval none
  */
void delay_sec(uint16_t sec)
{
  uint16_t index;
  for(index = 0; index < sec; index++)
  {
    delay_ms(500);
    delay_ms(500);
  }
}


